<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>xeokit Example</title>
    <link href="../css/pageStyle.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
    <style>
        #storeys {
            position: absolute;
            left: 10px;
            top: 60px;
            margin-top: 20px;
            overflow-y: scroll;
            height: calc(100% - 120px);
            margin-bottom: 10px;
            width: 600px;
            pointer-events: all;
            opacity: 1.0;
        }
    </style>
</head>
<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div id="storeys"></div>
<div class="slideout-sidebar">
    <img class="info-icon" src="../../assets/images/storey_views_icon.png"/>
    <h1>StoreyViewsPlugin</h1>
    <h2>UX Recipe #3</h2>
    <p>Click a room in the plan images to go there in <b>first-person mode</b>. </p>
    <h3>Components Used</h3>
    <ul>
        <li>
            <a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
               target="_other">Viewer</a>
        </li>
        <li>
            <a href="../../docs/class/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js~StoreyViewsPlugin.html"
               target="_other">StoreyViewsPlugin</a>
        </li>
        <li>
            <a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
               target="_other">XKTLoaderPlugin</a>
        </li>
        <li>
            <a href="../../docs/class/src/viewer/scene/camera/CameraFlightAnimation.js~CameraFlightAnimation.html"
               target="_other">CameraFlightAnimation</a>
        </li>
    </ul>
    <h3>Resources</h3>
    <ul>
        <li>
            <a href="https://github.com/openBIMstandards/DataSetSchependomlaan"
               target="_other">Model source</a>
        </li>
    </ul>
</div>
</body>

<script type="module">

    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import {Viewer, StoreyViewsPlugin, math, XKTLoaderPlugin, CameraMemento} from "../../dist/xeokit-sdk.min.es.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer, arrange the camera
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
        canvasId: "myCanvas",
        transparent: true,
        edges: true
    });

    viewer.camera.eye = [-2.56, 8.38, 8.27];
    viewer.camera.look = [13.44, 3.31, -14.83];
    viewer.camera.up = [0.10, 0.98, -0.14];

    viewer.cameraControl.navMode = "firstPerson";
    viewer.cameraControl.followPointer = true;

    //------------------------------------------------------------------------------------------------------------------
    // Load a model
    //------------------------------------------------------------------------------------------------------------------

    const xktLoader = new XKTLoaderPlugin(viewer);

    const sceneModel = xktLoader.load({
        id: "myModel",
        src: "../../assets/models/xkt/v10/ifc/ar-demo-sample-single-building-01.xkt",
        edges: true,
        objectDefaults: { // This model has opaque windows / spaces; make them transparent
            "IfcPlate": {
                opacity: 0.3 // These are used as windows in this model - make transparent
            },
            "IfcWindow": {
                opacity: 0.4
            },
            "IfcSpace": {
                opacity: 0.4
            }
        }
    });

    //------------------------------------------------------------------------------------------------------------------
    // Add a StoreyViewsPlugin
    //------------------------------------------------------------------------------------------------------------------

    const storeyViewsPlugin = new StoreyViewsPlugin(viewer, {
        fitStoreyMaps: true
    });

    //------------------------------------------------------------------------------------------------------------------
    // When model loaded, build a clickable set of storey plan images from the StoreyViewsPlugin, bind mouse
    // events to fly the Camera to a first-person view at whatever location we click within each plan view image
    //------------------------------------------------------------------------------------------------------------------

    sceneModel.on("loaded", function () {

        viewer.cameraFlight.jumpTo(sceneModel);

        // Make all doors transparent
        viewer.scene.setObjectsOpacity(viewer.metaScene.getObjectIDsByType("IfcDoor"), 0.3);

        buildStoreyMapsMenu();

    });

    function buildStoreyMapsMenu() {

        const cameraMemento = new CameraMemento(); // Saves 3D perspective camera to restore
        cameraMemento.saveCamera(viewer.scene);

        const storeyDiv = document.getElementById("storeys");
        const storeys = storeyViewsPlugin.storeysList;

        for (let i = 0, len = storeys.length; i < len; i++) {

            const storey = storeys[i];
            const storeyId = storey.storeyId;

            const storeyMap = storeyViewsPlugin.createStoreyMap(storeyId, {
                format: "png",
                width: 500
            });

            const img = document.createElement("img");
            img.src = storeyMap.imageData;
            img.style.border = "1px solid #000000";
            img.style.background = "lightblue";
            img.style.width = storeyMap.width + "px";
            img.style.height = storeyMap.height + "px";
            img.style.opacity = 0.9;

            storeyDiv.appendChild(img);

            img.onmouseenter = () => {
                img.style.cursor = "pointer";
            };

            img.onmouseleave = (e) => {
                img.style.cursor = "default";
            };

            img.onclick = (e) => {

                const imagePos = [e.offsetX, e.offsetY];

                const worldPos = storeyViewsPlugin.storeyMapToWorldPos(storeyMap, imagePos);

                if (worldPos) {


                    // Set camera vertical position at the mid point of the storey's vertical
                    // extents - note how this is adapts to whichever of the X, Y or Z axis is
                    // designated the World's "up" axis

                    const camera = viewer.scene.camera;
                    const idx = camera.xUp ? 0 : (camera.yUp ? 1 : 2); // Find the right axis for "up"
                    const storey = storeyViewsPlugin.storeys[storeyMap.storeyId];
                    worldPos[idx] = (storey.storeyAABB[idx] + storey.storeyAABB[3 + idx]) / 2;

                    viewer.cameraFlight.flyTo({
                        eye: worldPos,
                        up: viewer.camera.worldUp,
                        look: math.addVec3(worldPos, viewer.camera.worldForward, []),
                        projection: "perspective",
                        duration: 1.5
                    }, () => {
                        viewer.cameraControl.navMode = "firstPerson";
                    });
                }
            };
        }
    }


</script>
</html>
